using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Text.RegularExpressions;

namespace DiceRoller.GUI {

  public partial class frmMain : Form {

    private System.Collections.ArrayList history;
    private int index;

    public frmMain() {
      InitializeComponent();
      history = new System.Collections.ArrayList();
      index = 0;
      txtTarget.Text = "7";
    }

    private void btnRoll_Click(object sender, EventArgs e) {
      rollDice();
    }

    private void rollDice() {
      string sNumDice;
      int numDice;
      int[] rolledDice;

      sNumDice = txtNumberDice.Text;
      if(Regex.Match(sNumDice, "[0-9]+").Success && Regex.Match(txtTarget.Text, "[0-9]+").Success) {

        numDice = Convert.ToInt32(sNumDice);

        rolledDice = roll(numDice);

        txtDiceDisplay.Text = String.Empty;

        for(int i = 0; i < numDice; i++) {
          txtDiceDisplay.Text += (rolledDice[i]).ToString() + " ";
        }

        txtDiceDisplay.Text = txtDiceDisplay.Text.Trim();

        txtSuccesses.Text = (exaltedSuccesses(rolledDice)).ToString();
        setBotchedStatus();
        txtHistory.Text = txtSuccesses.Text + (txtSuccesses.Text.Equals("BOTCHED") ? "   " : " Successes") + " - " + txtDiceDisplay.Text + System.Environment.NewLine + txtHistory.Text;
        history.Add(sNumDice);
        index = history.Count - 1;
      }
    }

    private void setBotchedStatus() {
      if(txtSuccesses.Text.Trim().Equals("0") && countElements(txtDiceDisplay.Text.Split(), "1") >= 1 && !cboDamage.Checked) {
        txtSuccesses.Text = "BOTCHED";
      }
    }

    private int exaltedSuccesses(int[] rolledDice) {
      int successes = 0;

      for(int i = 0; i < rolledDice.Length; i++) {
        if(rolledDice[i] == 0) {
          successes += cboDamage.Checked ? 1 : 2;
        }
        else if(rolledDice[i] >= Convert.ToInt32(txtTarget.Text)) {
          successes += 1;
        }
      }
      return successes;
    }

    private int[] roll(int numDice) {
      int[] rolledDice = new int[numDice];
      System.Random r = new System.Random(Convert.ToInt32((DateTime.Now).Ticks % Int32.MaxValue));

      for(int i = 0; i < numDice; i++) {
        rolledDice[i] = r.Next(0, 9);
      }
      return rolledDice;
    }

    private void txtNumberDice_KeyDown(object sender, KeyEventArgs e) {
      switch(e.KeyCode) {
        case Keys.Enter:
          rollDice();
          break;
        case Keys.Escape:
          txtNumberDice.Text = "";
          txtNumberDice.Focus();
          break;
        case Keys.Up:
          if(index >= 1 && sender.Equals(txtNumberDice)) {
            txtNumberDice.Text = Convert.ToString(history.ToArray()[--index]);
          }
          break;
        case Keys.Down:
          if(index < history.Count - 1 && sender.Equals(txtNumberDice)) {
            txtNumberDice.Text = Convert.ToString(history.ToArray()[++index]);
          }
          break;
      }
    }

    private void cboDamage_CheckedChanged(object sender, EventArgs e) {
      string[] dice;
      int successes;
      int zeroes;

      if(!txtSuccesses.Text.Equals(System.String.Empty)) {
        if(!txtSuccesses.Text.Equals("BOTCHED")) {
          successes = Convert.ToInt32(txtSuccesses.Text);
        }
        else {
          successes = 0;
        }


        dice = txtDiceDisplay.Text.Split(" ".ToCharArray());

        zeroes = countElements(dice, "0");

        txtSuccesses.Text = (cboDamage.Checked ? successes - zeroes : successes + zeroes).ToString();
        setBotchedStatus();
        txtHistory.Text = txtSuccesses.Text + (txtSuccesses.Text.Equals("BOTCHED") ? "   " : " Successes") + " - " + txtDiceDisplay.Text + System.Environment.NewLine + txtHistory.Text;
      }
    }

    private int countElements(object[] list, object element) {
      int count = 0;
      for(int i = 0; i < list.Length; i++) {
        count += list[i].Equals(element) ? 1 : 0;
      }
      return count;
    }

  }
}
